/**********************************
|   Author	: XForce              |
|   Website	: xforce.square7.ch   |
|                                 |
***********************************/


#include "stdafx.h"

#define WINDOW_NAME "SimpleSample"

using namespace std;

ID3DXFont *xfont = NULL;
ID3DXFont *nfont = NULL;
//bool initx = false;
HHOOK MouseHook;
HHOOK KeyboardHook;
HWND hwnd;
RECT client;

bool mousedown;
XGUI* ui;
std::vector <XWindow> *windowsp;
std::vector <XControl*> *controlsp;
std::vector <Control*> *contsp;
std::vector <XListBoxItem> *itemsp;

//LPD3DXLINE g_pLine;


#ifndef PI 
#define PI    3.14159265358979323846f 
#endif 









int caltext(std::string textbuffer)
{
	RECT r = {0, 0, 0, 0};
	char* pText = (char*)textbuffer.c_str();
	int len = strlen( pText );
	if( len == 0 ) 
		return 0;

	char lastChar = pText[ len-1 ];
	if( lastChar == ' ' )  
		pText[ len-1 ] = '_';
	xfont->DrawText( NULL, pText, -1, &r, DT_CALCRECT , 0xffffffff );
	pText[len-1] = lastChar; 
	return r.right - r.left;
}
// Restore last character.return r.right - r.left;
int caltexth(std::string textbuffer)
{
	RECT r = {0, 0, 0, 0};
	char* pText = (char*)textbuffer.c_str();
	int len = strlen( pText );
	if( len == 0 ) 
		return 0;

	char lastChar = pText[ len-1 ];
	if( lastChar == ' ' )  
		pText[ len-1 ] = '_';
	xfont->DrawText( NULL, pText, -1, &r, DT_CALCRECT , 0xffffffff );
	pText[len-1] = lastChar; 
	return r.bottom - r.top;
}
	BYTE UnlockMouse[3] = {0xC2, 0x08, 0x00};
	BYTE LockMouse[3] = {0x8B,0xFF,0x55};



	void Lockmouse(bool lock)
	{
		if(!lock)
		{
				HMODULE hMyMod = NULL;
						hMyMod = GetModuleHandle("USER32.dll");

						if(hMyMod)
						{
							DWORD dwTemp = NULL;
							dwTemp =    (DWORD)GetProcAddress(hMyMod, "SetCursorPos");

							if(dwTemp)
							{
								DWORD dwProtect;
								VirtualProtect((void*)dwTemp, 3, PAGE_EXECUTE_READWRITE, &dwProtect);
								memcpy((void*)dwTemp, &UnlockMouse, 3);
								VirtualProtect((void*)dwTemp, 3, dwProtect, &dwProtect);
							}
						}
		}
		else
		{
		HMODULE hMyMod = NULL;
						hMyMod = GetModuleHandle("USER32.dll");

						if(hMyMod)
						{
							DWORD dwTemp = NULL;
							dwTemp =    (DWORD)GetProcAddress(hMyMod, "SetCursorPos");

							if(dwTemp)
							{
								DWORD dwProtect;
								VirtualProtect((void*)dwTemp, 3, PAGE_EXECUTE_READWRITE, &dwProtect);
								memcpy((void*)dwTemp, &LockMouse, 3);
								VirtualProtect((void*)dwTemp, 3, dwProtect, &dwProtect);
							}
						}
		}
	}


LRESULT CALLBACK KeyboardHookProc (int nCode, WPARAM wParam, LPARAM lParam)	
{


	if  (nCode == HC_ACTION)      
	{
		if ((nCode == HC_ACTION) && 
		((wParam == WM_SYSKEYDOWN) ||
		(wParam == WM_KEYDOWN)
		)) {
				KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*)lParam;
				
				if(key->vkCode == VK_F8)
				{
					addToChatWindow("This is a screenshot of XHud",D3DCOLOR_ARGB(255,0xEE,0x55,0x55));
					//addMessageToChatWindow("This is a Scrennshot of XHud");
					dhud = true;
				}
				
				if(key->vkCode == VK_INSERT)
					if(ui->disabled)
					{
						Lockmouse(false);
						
						ShowCursor(true);
						ui->disabled = false;
					}else if( !ui->disabled)
					{
						Lockmouse(true);
						ui->disabled = true;
						
						ShowCursor(false);
					}
		}



		if ((nCode == HC_ACTION) && 
		((wParam == WM_SYSKEYUP) ||
		(wParam == WM_KEYUP)
		)) {
		KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*)lParam;
				
				if(key->vkCode == VK_F8)
				{
					dhuddelay = GetTickCount() + 1000;
					dhud = false;
				}
		}
		//for(vector<Control*>::iterator control = controls->begin();
		//std::vector<XWindow*> windows;

		//for(std::vector<Control*>::iterator control = 
		/*for (vector<Control*>::iterator control = contsp->begin(); control != contsp->end(); ++control) 
		{
			Control* cont;
			cont = *control._Ptr;
			if(cont->type == ControlTypes::Textboxs)
			{cont->HandleInput(nCode,wParam,lParam);break;}
		}*/
		for (vector<XControl*>::iterator control = controlsp->begin(); control != controlsp->end(); ++control) {
			XControl* cont;
		cont = *control._Ptr;
			if(cont->type == types::Textbox && cont->active == 1)
				{XTextBox* tb;
			tb = (XTextBox*)*control._Ptr;
					tb->HandleInput(nCode,wParam,lParam);break;}
		}
	}else return 0;


	return CallNextHookEx(KeyboardHook,
		nCode,wParam,lParam);

}

DWORD downtick;
short zDelta;

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{   
	if( nCode == 0 ) // means: nCode==HC_ACTION or nCode==HC_NOREMOVE 
	{ 

		//PMSLLHOOKSTRUCT k = (PMSLLHOOKSTRUCT)(lParam);  
		
		//MOUSEHOOKSTRUCT mhs = *(MOUSEHOOKSTRUCT*)lParam;

		//GetCursorPos(&p);
		MOUSEHOOKSTRUCTEX* info = (MOUSEHOOKSTRUCTEX*)( lParam );
		POINT p;   
		p=info->pt;						
		ScreenToClient(hwnd,&p);//FindWindow(NULL,/*"SimpleSample"*/WINDOW_NAME),&p);
		int xMetric = GetSystemMetrics(SM_CXVIRTUALSCREEN); 

		xMetric -= 100; 
		

	/*	if(wParam == WM_LBUTTONDOWN)      
		{
			for(std::vector<Control*>::iterator cont = contsp->begin(); cont != contsp->end();++cont)
			{
				Control* control;
				control = *cont._Ptr;
				switch(control->type)
				{
				case ControlTypes::NumericUpDowns:
					if(p.x <= control->x  + control->window->x + 20 +2 && p.x > control->x + control->window->x -2 && p.y <= control->y + control->window->y  +control->h/4 + control->h/2 + 2&& p.y > control->y + control->window->y +control->h/4 -2)
					{
						if(control->value - control->step >= control->min)
						{ 
							control->value -= control->step; 
							control->mouse = 1;
						}
					}
					if(p.x <= control->x  + control->window->x +control->w + 2 && p.x > control->x + control->window->x +control->w -20 -2 && p.y <= control->y + control->window->y  +control->h/4 + control->h/2 + 2&& p.y > control->y + control->window->y +control->h/4 -2)
					{
						if(control->value + control->step <= control->max)
						{ 
							control->value += control->step; 
							control->mouse = 2;
						}
					}
					break;
				case ControlTypes::ListBoxs:
					if( p.x >= control->x +control->window->x + control->w -17 && p.y  >= control->y +control->window->y + control->slidery && p.y <= control->y + control->window->y + (control->items.size() * 17) / control->h * 17 + control->slidery && p.x <= control->x +control->window->x + control->w)
					{
						control->slidermouse = 1;
					}
					break;
				}
			}
		}
*/

		if(wParam == WM_LBUTTONDOWN)      
		{     

			//MessageBox(NULL,"Test","Test",0);	
			for (vector<XControl*>::iterator cont = controlsp->begin(); cont != controlsp->end(); ++cont) {
				
				XControl* control;
				control = *cont._Ptr;
				if(control->type == ::NumericUpDown)
				{
					XNumericUpDown* nud;
					nud = (XNumericUpDown*)*cont._Ptr;
					if(p.x <= nud->x  + nud->window->x + 20 +2 && p.x > nud->x + nud->window->x -2 && p.y <= nud->y + nud->window->y  +nud->h/4 + nud->h/2 + 2&& p.y > nud->y + nud->window->y +nud->h/4 -2)
					{
						if(nud->value - nud->step >= nud->min)
						{ 
							nud->value -= nud->step; 
							nud->mouse = 1;
						}
					}
					if(p.x <= nud->x  + nud->window->x +nud->w + 2 && p.x > nud->x + nud->window->x +nud->w -20 -2 && p.y <= nud->y + nud->window->y  +nud->h/4 + nud->h/2 + 2&& p.y > nud->y + nud->window->y +nud->h/4 -2)
					{
						if(nud->value + nud->step <= nud->max)
						{ 
							nud->value += nud->step; 
							nud->mouse = 2;
						}
					}
					//nud->x + nud->window->x , nud->y + nud->window->y + (nud->h/2)/2, 20 ,nud->h/2 +1
				}
				if(control->type == ::ListBox)
				{
					XListBox* ltb;
					ltb = (XListBox*)*cont._Ptr;
					if( p.x >= ltb->x +ltb->window->x + ltb->w -17 && p.y  >= ltb->y +ltb->window->y + ltb->slidery && p.y <= ltb->y + ltb->window->y + (ltb->items.size() * 17) / ltb->h * 17 + ltb->slidery && p.x <= ltb->x +ltb->window->x + ltb->w)
					{ltb->slidermouse = 1;}
				}
			}
			downtick = GetTickCount();
			mousedown = true;  
		}
		if(wParam == WM_LBUTTONUP)
		{


			
			mousedown = false;
			for (vector<XControl*>::iterator cont = controlsp->begin(); cont != controlsp->end(); ++cont) {
				
				XControl* control;
				control = *cont._Ptr;
				switch(control->type)
				{
				case ::Button:
					XButton* btn;
					btn = (XButton*)*cont._Ptr;
					if(p.x <= btn->x + btn->w + btn->window->x  && p.x > btn->x + btn->window->x && p.y <= btn->y + btn->h +btn->window->y  && p.y > btn->y + btn->window->y)
					{
						/*std::stringstream ss (stringstream::in | stringstream::out);
						ss << p.x << " " << p.y << " " <<  btn->x << " " << btn->y << " " << btn->w << " " << btn->h;
						MessageBox(NULL,ss.str().c_str(),"Test",0);	*/
						mousedown = false;
						CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)btn->clickevent, (LPVOID)btn, NULL, NULL);
					}	
					break;
				case ::Textbox:
					XTextBox* tb;
					tb = (XTextBox*)*cont._Ptr;
					if(p.x <= tb->x + tb->w + tb->window->x  && p.x > tb->x + tb->window->x && p.y <= tb->y + tb->h +tb->window->y  && p.y > tb->y + tb->window->y)
					{
						/*std::stringstream ss (stringstream::in | stringstream::out);
						ss << p.x << " " << p.y << " " <<  tb->x << " " << tb->y << " " << tb->w << " " << tb->h;
						MessageBox(NULL,ss.str().c_str(),"Test",0);	*/
						tb->active = 1;
					}
					else
						tb->active = 0;
					break;
				case ::NumericUpDown:	
					XNumericUpDown* nud;
					nud = (XNumericUpDown*)*cont._Ptr;
					nud->mouse = 0;
					/*if(p.x <= nud->x  + nud->window->x + 20 +2 && p.x > nud->x + nud->window->x -2 && p.y <= nud->y + nud->window->y  + nud->h/2 +2 && p.y > nud->y + nud->window->y +nud->h/4 -2)
					{nud->value += nud->step; nud->mouse = 1;}*/
					break;
				case ::ListBox:
					XListBox* ltb;
					ltb = (XListBox*)*cont._Ptr;
					int i = 0;

					if(!ltb->slidermouse)
					{
						int n = 0;
repeat:
						if(p.x <= ltb->x + ltb->w + ltb->window->x -17 && p.x > ltb->x + ltb->window->x && p.y <= ltb->y + ltb->window->y + n*17  +17 && p.y > ltb->y + ltb->window->y + n*17)
						{
							ltb->selected = n + ltb->out;	

							//break;
						}
						/*else
						{ltb->selected = -1;}*/

						n++;

						if(n*17+17 < ltb->h)
							goto repeat;
						if(p.x <= ltb->x + ltb->w + ltb->window->x -17)
						{
							for (vector<XListBoxItem>::iterator item = itemsp->begin(); item != itemsp->end(); ++item) 
							{
								if(i == ltb->selected)
									item->selected = 1;
								else
									item->selected = 0;
								i++;
							}
						}
					}
					ltb->slidermouse = 0;
					break;
				}
			}
		}

	} 




	return CallNextHookEx(MouseHook,nCode,wParam,lParam); 
}



DWORD WINAPI XGUI::hooks(LPVOID lpParm)
{
	HINSTANCE hInstance = GetModuleHandle(NULL);
	if (!hInstance) hInstance = LoadLibrary((LPCSTR)lpParm); 
	if (!hInstance) return 1;

	//while(true)
	//{
	MouseHook = SetWindowsHookEx (  
		WH_MOUSE_LL,
		(HOOKPROC)MouseHookProc,  
		hInstance,                 
		NULL                       
		);


	KeyboardHook = SetWindowsHookEx (  
		WH_KEYBOARD_LL,
		(HOOKPROC)KeyboardHookProc,  
		hInstance,                 
		NULL                       
		);

	//MessageLoop();
	MSG msg;
	//HACCEL hAccelTable;
	//hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_KEYBINDER));
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	UnhookWindowsHookEx(MouseHook);
	UnhookWindowsHookEx(KeyboardHook);

	//}

	return 0;
}


#define GR_GREEN2 D3DCOLOR_ARGB( 255, 120, 154,116 ),D3DCOLOR_ARGB( 255, 16, 102, 9 )
#define GR_GREEN1 D3DCOLOR_ARGB( 255, 76, 135, 000 ),D3DCOLOR_ARGB( 255, 116, 205, 000 )
#define GR_RED1 D3DCOLOR_ARGB( 255, 255, 000, 51 ),D3DCOLOR_ARGB( 255, 156, 000, 31 )
#define GR_BTNDOWN D3DCOLOR_ARGB( 255,136, 109, 180 ),D3DCOLOR_ARGB( 255, 38,5, 75 )
#define GR_BARB D3DCOLOR_ARGB( 255,48, 48, 48 ),D3DCOLOR_ARGB( 255, 17,17, 17 )
#define GR_NUMB D3DCOLOR_ARGB( 255,60, 60, 60 ),D3DCOLOR_ARGB(90, 30,30,30 )


#pragma region XControl



void XTextBox::HandleInput(int nCode, WPARAM wParam, LPARAM lParam)
{
	//int tmp;
	//int spos;
	charw = caltext("A");

	KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*)lParam;
	if ((nCode == HC_ACTION) && 
		((wParam == WM_SYSKEYDOWN) ||
		(wParam == WM_KEYDOWN)
		)) 
	{
		BYTE keyState[256] = {0};
		WORD chars;
				GetKeyState(0);

		GetKeyboardState(keyState);
		if(ToAscii(key->vkCode, key->scanCode,keyState, &chars, 0))
		{

			if(key->vkCode == VK_DELETE)
			{
				//textbuffer.erase(caretPos+1,1);
			}
			else if((char)chars == '\b')
				 {
				if(caretPos > 0)
				{



				if(x +window->x+((caretPosScreen-1)*charw) >= x+window->x && ((showPosbegin <= 0) || (textbuffer.substr(showPosbegin,textbuffer.length()).length()*charw > this->w)))
					caretPosScreen -=1;
		

				if(showPosbegin > 0 && textbuffer.substr(showPosbegin,textbuffer.length()).length()*charw < this->w)
					showPosbegin -=1;




			if(caretPos-1 >= 0)
			{
				caretPos-=1;
				textbuffer.erase(caretPos,1);
			}
			else
				textbuffer.erase(caretPos-1,1);


       
				//if(textbuffer.substr(showPosbegin,textbuffer.npos).length()*charw < this->w)

				
				}
			 }
			 else
			 {
		textbuffer.insert(caretPos,1,(char)chars);
	if(x + window->x + ((caretPosScreen+2)*charw) < x +window->x + w)
	{caretPos +=1;caretPosScreen+=1;}
	else
	{caretPos+=1; showPosbegin +=1;}
			 }			
		}
		
		if(key->vkCode == VK_RIGHT)
		{
			if(x + window->x + ((caretPosScreen)*charw) > x +window->x + w -charw -(charw/2))
			{
					
				//if(showPosbegin < )
					if(caretPos < textbuffer.length())
						{showPosbegin +=1;caretPos+=1;}
				//control->x +control->window->x+(control->caretPos*8);
			}
			else
			{
				if(caretPos < textbuffer.length())
				{caretPos +=1;
				caretPosScreen +=1;}
			}
		}

		if(key->vkCode == VK_LEFT)
		{
			if(x +window->x+((caretPosScreen-1)*charw) < x+window->x)
			{
				
				if(showPosbegin > 0)
				{showPosbegin -=1; caretPos -=1;}//caretPos-=1;}
			}
			else
			{
				caretPosScreen -=1;
				caretPos -=1;
			}
			
		}
	}

}

void XControl::Render(LPDIRECT3DDEVICE9 Device)
{
	
	std::string tmp;
	std::stringstream ss (stringstream::in | stringstream::out);
	switch(this->type)
	{
	case types::Textbox:
		XTextBox* tb;
		tb = (XTextBox*)this;
		tb->Render(Device);
		break;
	case types::Button:
		XButton* btn;
		btn = (XButton*)this;
		btn->Render(Device);
		break;
	}
}

//void XControl::takeInput(char ch)
//{
//	
//	MessageBox(NULL,(char*)ch,(char*)ch,0);
//		switch(ch)
//		{
//		case '\b':    // backspace
//			{
//				if(caretPos>0)
//				{
//					textbuffer.erase(caretPos-1,1);
//					caretPos-=1;
//				}
//			}
//			break;
//
//		case '\r':    // return/enter
//			{
//				//prevCommands.push_back(command);
//
//				//Send(command);
//
//				textbuffer="";
//				caretPos=0;
//				//cmdCount=prevCommands.size();
//				//currCmd=cmdCount;
//			}
//			break;
//
//		case '\t':    // tab
//			{
//				/* if(cmdCount>0)
//				{
//				if(currCmd>0)
//				{
//				currCmd-=1;
//				command=prevCommands.at(currCmd);
//				caretPos=command.length();
//				}
//				else
//				{
//				currCmd=cmdCount-1;
//				command=prevCommands.at(currCmd);
//				caretPos=command.length();
//				}
//				}*/
//			}
//			break;
//
//		default:
//			
//			textbuffer.insert(caretPos,1,ch);
//			
//			caretPos+=1;
//			break;
//		} // switch(ch)
//}

#pragma endregion



#pragma region XNumeric

XNumericUpDown::XNumericUpDown()
{
	this->max = 100.0f;
	this->min = 0.0f;
	this->step = 1.0f;
}

XNumericUpDown::XNumericUpDown(int x,int y,int h,int w, std::string title,int id)
{
	this->type = ::NumericUpDown;
	this->x = x;
	this->y = y;
	this->h = h;
	this->w = w;
	this->id = id;
	this->max = 100.0f;
	this->min = 0.1f;
	this->step = 0.1f;
}

DWORD wtick;

void XNumericUpDown::Render(LPDIRECT3DDEVICE9 Device)
{
	if(mousedown && downtick + 500 <= GetTickCount() && mouse == 1)
	{
		if(value - step >= min)
		value -= step;
	}
	
	if(mousedown && downtick + 500 <= GetTickCount() && mouse == 2)
	{
		if(value + step <= max)
		value += step;
	}

	std::stringstream ss (stringstream::in | stringstream::out);
					ss << value;
		RECT rctt;
		rctt.left = this->x +window->x;
		rctt.right = this->x +window->x+ this->w;
		rctt.top = this->y +window->y;
		rctt.bottom = this->y + window->y + this->h;
		
	xfont->DrawText(NULL, ss.str().c_str(),-1,&rctt,DT_CENTER,D3DCOLOR_ARGB( 255, 255, 255, 0 ));

	FullRectBordered(this->x + window->x , this->y +window->y + this->h/4 , 20 ,this->h/2 +1,2,GR_RED1);//,0,Device);
	rctt.left = this->x +window->x + 3;
	nfont->DrawText(NULL, "<<<",-1,&rctt,DT_LEFT | DT_VCENTER,D3DCOLOR_ARGB( 255, 255, 255, 255 ));


	FullRectBordered(this->x + window->x + this->w - 20, this->y +window->y + this->h/4 , 20 ,this->h/2 +1,2,GR_RED1);//,0,Device);
	rctt.right = this->x +window->x+ this->w - 3;
	nfont->DrawText(NULL, ">>>",-1,&rctt,DT_RIGHT | DT_VCENTER,D3DCOLOR_ARGB( 255, 255, 255, 255 ));

}

#pragma endregion

#pragma region XTextBox


XTextBox::XTextBox()
{

}


XTextBox::XTextBox(int x,int y,int h,int w,int id)
{
	this->type = ::Textbox;
	this->x = x;
	this->y = y;
	this->h = h;
	this->w = w;
	this->id = id;
	this->caretPos = 0;
	this->showPosbegin = 0;
	this->caretPosScreen = 0;
	
}


void XTextBox::Render(LPDIRECT3DDEVICE9 Device)
{
	DrawRectBordered(this->x +window->x , this->y +window->y,this->w, this->h,D3DCOLOR_ARGB( 155, 000, 000, 000 ),D3DCOLOR_ARGB( 255, 120, 154,116 ));
	
		int length;
		RECT rctt;
		rctt.left = this->x +window->x +6;
		rctt.right = this->x +window->x+ this->w;
		rctt.top = this->y +window->y;
		rctt.bottom = this->y + window->y + this->h;

	length = caltext(textbuffer);
	if(showPosbegin > 0)
		
	{if(w == 0 || charw == 0){ MessageBox(NULL,"Es ist ein fehler aufgetreten\n bitte kontaktiere den entwickler","Error",MB_ICONEXCLAMATION | MB_OK); ExitProcess(0);}
	xfont->DrawText(NULL, textbuffer.substr(showPosbegin,(this->w/charw)).c_str(),-1,&rctt,0,D3DCOLOR_ARGB( 255, 255, 255, 0 ));}
	else
		xfont->DrawText(NULL,textbuffer.c_str(),-1,&rctt,0,D3DCOLOR_ARGB( 255, 255, 255, 0 ));

		/*caretTick+=1;
    if ( caretTick >= 25)
        {
            caretTick=0;
            showCaret=!showCaret;
        }    */
    if(ltick +750 <= GetTickCount() && active)
	{
		if(ltick + 1500 <= GetTickCount())
			ltick = GetTickCount();
		//caretPos = 8;
		
		//if(this->x +window->x+((caretPos+1)*8) <= this->x +window->x + this->w)
		//{
			rctt.left = this->x +window->x+ (caretPosScreen*charw);
		//}
			DrawLine(rctt.left+7,this->y + window->y + 2,rctt.left +7,this->y + window->y + this->h - 2,1,D3DCOLOR_ARGB(255,255,255,0));
	//	xfont->DrawText(NULL,"|",-1,&rctt,0,D3DCOLOR_ARGB( 255, 255, 255, 0 ));
        //Text(x+6+(caretPos*8),y+2,D3DCOLOR_ARGB( 255, 255, 165, 0 ),"|",pDevice);
	}
		//GradientRect(this->x +window->y , this->y +window->y, this->h,this->w,GR_GREEN2);
}


#pragma endregion



#pragma region XButton


XButton::XButton()
{

}


XButton::XButton(int x,int y,int h,int w, std::string title,void (*func)(XButton* sender),int id)
{

	this->type = types::Button;
	this->x = x;
	this->y = y;
	this->h = h;
	this->w = w;
	this->title += title.c_str();
	this->id = id;
	this->clickevent = func;
}

void XButton::Render(LPDIRECT3DDEVICE9 Device)
{
	POINT p;
		GetCursorPos(&p);
		ScreenToClient(hwnd,&p);//FindWindow(NULL,/*"SimpleSample"*/WINDOW_NAME),&p);
		if(mousedown &&  p.x <= this->x + this->w +window->x  && p.x > this->x + window->x && p.y <= this->y + this->h +window->y  && p.y > this->y + window->y)
		{
			GradientRect(this->x +window->x , this->y +window->y, this->h,this->w,GR_BTNDOWN);//,0,Device);

		}
		else if(p.x <= this->x + this->w +window->x  && p.x > this->x + window->x && p.y <= this->y + this->h +window->y  && p.y > this->y + window->y)
		{
			GradientRect(this->x +window->x , this->y +window->y, this->h,this->w,GR_GREEN1);//,0,Device);
		}
		else
		{
			GradientRect(this->x +window->x , this->y +window->y, this->h,this->w,GR_GREEN2);//,0,Device);
		}
		RECT rct;
		rct.left = this->x + window->x;
		rct.top = this->y + window->y;
		rct.right = this->w +window->x +this->x;
		rct.bottom = this->h + window->y +this->y;
		xfont->DrawText(NULL,this->title.c_str(),-1,&rct,DT_NOCLIP | DT_CENTER | DT_VCENTER ,D3DCOLOR_ARGB( 255, 255,255, 255 ));
}

#pragma endregion



#pragma region XListBox


XListBox::XListBox()
{
	this->slidery = 0;
};

XListBox::XListBox(int x,int y,int h,int w, std::string title,int id) 
{
		this->type = ::ListBox;
	this->x = x;
	this->y = y;
	this->h = h;
	this->w = w;
	this->id = id;
	this->title = title;
	//for(int i = 0; i< 50;i++)
	//{
	//	XListBoxItem item;
	//	item.name = "Test";
	//	item.name += i;
	//	item.selected = 0;
	//		//item.selected = i;
	//	items.push_back(item);
	//}
}

POINT oldp;
void XListBox::Render(LPDIRECT3DDEVICE9 pDevice)
{

	itemsp = &items;
	int charh = caltexth("A");
	int sliderh =((float)items.size()*17 / (float)this->h);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);//FindWindow(NULL,/*"SimpleSample"*/WINDOW_NAME),&p);
	DrawRectBordered(this->x +window->x , this->y +window->y,this->w, this->h,D3DCOLOR_ARGB( 155, 000, 000, 000 ),D3DCOLOR_ARGB( 255, 120, 154,116 ));
	
	

	int n = 0;
		RECT rct;
		rct.left = this->x + window->x + 2;
		rct.top = this->y + window->y +2;
		rct.right = this->w +window->x +this->x;
		rct.bottom = this->h + window->y +this->y;
		int oldslidery;
		if(sliderh > 0)
		{
		if(slidermouse == 1)
		{
			
			//if(p.y > this->y + window->y && p.y < this->y + window->y + this->h)
				slidery = p.y  -oldp.y + slidery;

			if(sliderh + slidery > this->h)
				slidery = this->h -sliderh -1;

			if(slidery < 0)
				slidery = 1;

			oldslidery  = slidery;
		}
		out = ((float)items.size() / (float)this->h) * slidery;
		}

		
		RECT rctt;
		rctt.left = 250;
		rctt.top = 250;
		rctt.right = 10000;
		rctt.bottom =1000;
				stringstream ss (stringstream::in| stringstream::out);
		ss << sliderh;
		ss << "  " << p.y << "   " << zDelta;
		// xfont->DrawText(NULL,ss.str().c_str(),-1,&rctt,0,D3DCOLOR_ARGB( 255, 255,255, 255 ));
		GradientRect(this->x +window->x + this->w -15 , this->y +window->y + slidery, sliderh ,15,GR_BTNDOWN);//,0,Device);

		

			//DrawRectBordered(this->x +window->x , this->y + window->y +2 + this->selected * 17 ,this->w -15, 17,D3DCOLOR_ARGB( 200, 255, 000, 000 ),D3DCOLOR_ARGB( 255, 120, 154,116 ));
	
		

	for (vector<XListBoxItem>::iterator item = items.begin() + out; item != items.end(); ++item) {
		rct.top = this->y + window->y +2 + n*17;
		if(rct.top > rct.bottom)
			break;

		
		if(item->selected)
				DrawRectBordered(this->x +window->x , this->y + window->y +2 + /*this->selected*/n * 17 ,this->w -17, 17,D3DCOLOR_ARGB( 200, 255, 000, 000 ),D3DCOLOR_ARGB( 255, 120, 154,116 ));
		
		xfont->DrawText(NULL,item->name.c_str(),-1,&rct,0,D3DCOLOR_ARGB( 255, 255,255, 255 ));
		
	
		n++;
	}
	//XListBoxItem item;
	//item = this->GetSelectedItem();
			
	//rct.top = this->h + window->x + 17;

	//xfont->DrawText(NULL,item.name.c_str(),-1,&rct,0,D3DCOLOR_ARGB( 255, 255,255, 255 ));


	if(sliderh + slidery +1 < this->h && p.y > this->y + window->y)
		oldp = p;
	//<∨∧>
}

void XListBox::RemoveItem(XListBoxItem item)
{
	for (vector<XListBoxItem>::iterator itemb = items.begin() + out; itemb != items.end(); ++itemb) {
		if(itemb->info == item.name && itemb->info == item.info)
		{
			items.erase(itemb);
		}
	}
}

void XListBox::AddItem(XListBoxItem item)
{
	items.push_back(item);
}


XListBoxItem XListBox::GetSelectedItem()
{

	XListBoxItem item;

	for (vector<XListBoxItem>::iterator itemb = items.begin(); itemb != items.end(); ++itemb) {
		if(itemb->selected == 1)
		{
			item = *itemb._Ptr;
			return item;	
		}
	}


	item.name = "Nothing selected";
	item.info = "Nothing";
	item.selected = 1;
	return item;
}

#pragma endregion

#pragma region XWindow

XWindow::XWindow()
{};


XWindow::XWindow(int x,int y,int h,int w, std::string title,int id)
{
	this->x = x;
	this->y = y;
	this->h = h;
	this->w = w;
	this->id = id;
	this->title += title.c_str();
	this->state = WindowState::Normal;
	controlsp = &controls;

}

DWORD tick;

POINT woldp;
void XWindow::Render(LPDIRECT3DDEVICE9 Device)
{

		POINT p;
		GetCursorPos(&p);
		
		ScreenToClient(hwnd,&p);//FindWindow(NULL,/*"SimpleSample"*/WINDOW_NAME),&p);
		
		if(mousedown)
		{
		//	this->y = p.y  -woldp.y + this->y;
			//this->x = p.x  -woldp.x + this->x;
		}


	position.x = this->x;
	position.y = this->y;

	DrawRectBordered(this->x -1, this->y -1, this->w + 1,this->h + 1,D3DCOLOR_ARGB( 155, 000, 000, 000 ),D3DCOLOR_ARGB( 255, 000, 255, 000 ));
	GradientRect(this->x , this->y, 20,this->w,GR_BARB);

	//Rounded( this->x, this->y, this->w, 20, 2, D3DCOLOR_ARGB( 155, 255, 000, 000 ));
	//Rounded( this->x , this->y + 20, this->w, this->h, 2, D3DCOLOR_ARGB( 155, 000, 000, 000 ));
	RECT rct;
	rct.left = this->x;
	rct.top = this->y;
	rct.right = this->x + this->w;
	rct.bottom = 50;

	xfont->DrawText(NULL,this->title.c_str(),-1,&rct,DT_NOCLIP | DT_CENTER,this->textcolor);
	rct.top = this->y + this->h - 20;
	rct.left = this->x + 5;
	xfont->DrawText(NULL,"by XForce",-1,&rct,DT_NOCLIP,this->textcolor);
	controlsp = &controls;


	for (vector<XControl*>::iterator control = controls.begin(); control != controls.end(); ++control) {
			
		XControl* cont;
		cont = *control._Ptr;
		cont->Render(Device);
		//control->Render(Device);

	}

	woldp = p;
}


void XWindow::AddControl(XControl* control)
{
	/*control.window->x = this->x;
	control.window->y = this->y;
	control.caretPos = 0;
	control.showPosbegin = 0;
	control.caretPosScreen = 0;
	controls.push_back(control);*/
	position.x = this->x;
	position.y = this->y;
	control->window = &position;
	/*control->window->x = this->x;
	control->window->y = this->y;*/
	controls.push_back(control);

	controlsp = &controls;

}



void XWindow::RemoveControl(XControl* control)
{
	for (vector<XControl*>::iterator controli = controls.begin(); controli < controls.end(); ++controli) {
		XControl* cont;
		cont = *controli._Ptr;
		if(cont->id == control->id)
		{controls.erase(controli);
		return;
		}
		/*if(controli->id == control.id)
		{controls.erase(controli);
		return;
		}*/
	}
}

#pragma endregion





#pragma region XGUI

void XGUI::AddWindow(XWindow* window)
{
	windows.push_back(window);
}



void XGUI::RemoveWindow(XWindow* window)
{
	

	for (vector<XWindow*>::iterator windowi = windows.begin(); windowi != windows.end(); ++windowi) {
		XWindow* wind;
		wind = *windowi._Ptr;
		if(wind->id == window->id)
		{windows.erase(windowi);
		return;}
		}
}


void XGUI::Render(LPDIRECT3DDEVICE9 pDevice/*,D3DVIEWPORT9 viewport,ID3DXFont* xfont*/)
{
	//SetCursorPos(50,50);
	//ShowCursor(true);

	if( !g_pLine )
		D3DXCreateLine( pDevice, &g_pLine ); // Make sure to create before calling 

	if(!xfont)
		D3DXCreateFont(pDevice, (UINT)20, 0, FW_NORMAL, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY , DEFAULT_PITCH | FF_DONTCARE, TEXT("Courier New"), &xfont);

	if(!nfont)
		D3DXCreateFont(pDevice, (UINT)15, 6, FW_NORMAL, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY , DEFAULT_PITCH | FF_DONTCARE, TEXT("Courier New"), &nfont);
	if(!disabled)
	{
	XWindow* aw;
	bool awb = false;
	for (vector<XWindow*>::iterator window = windows.begin(); window != windows.end(); ++window) {
		XWindow* wind;
		wind = *window._Ptr;
		if(wind->state == WindowState::Active)
		{aw = wind; awb = true;}
		else if(wind->state != WindowState::Hide)
			wind->Render(pDevice);
	}
	if(awb)
	  aw->Render(pDevice);
	}
}



XGUI::XGUI()
{
	


	ui = this;
	//ShowCursor(true);
	this->disabled = true;
	CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)hooks, NULL, NULL, NULL);


	HWND hw = GetTopWindow(0 );
	DWORD cPid = GetCurrentProcessId();
while ( hw )
{
  DWORD pid;
  DWORD dwTheardId = ::GetWindowThreadProcessId( hw,&pid);



         if ( pid == cPid /*your process id*/ )
         {
			 hwnd = hw;
              break;
         }
         hw = GetNextWindow( hw , GW_HWNDNEXT);
}



}



void  XGUI::Release()
{
	//if(xfont)
		SAFE_RELEASE(xfont);
		SAFE_RELEASE(nfont);
		SAFE_RELEASE(g_pLine);
}



#pragma endregion